import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, Not, In } from 'typeorm';
import { Match } from './entities/match.entity';
import { MatchPreference } from './entities/match-preference.entity';
import { User } from '../users/entities/user.entity';
import { UserRecommendationDto } from '../users/dto/user-recommendation.dto';
import { CreateMatchDto } from './dto/create-match.dto';
import { CreateMatchPreferenceDto } from './dto/create-match-preference.dto';
import { UpdateMatchPreferenceDto } from './dto/update-match-preference.dto';
import { ChatService } from '../chat/chat.service';

@Injectable()
export class MatchService {
  constructor(
    @InjectRepository(Match)
    private matchRepository: Repository<Match>,
    @InjectRepository(MatchPreference)
    private matchPreferenceRepository: Repository<MatchPreference>,
    @InjectRepository(User)
    private userRepository: Repository<User>,
    private chatService: ChatService,
  ) {}

  // 创建或更新用户的匹配偏好
  async createOrUpdatePreference(
    userId: number,
    createMatchPreferenceDto: CreateMatchPreferenceDto,
  ): Promise<MatchPreference> {
    // 查找用户是否已有匹配偏好
    let preference = await this.matchPreferenceRepository.findOne({
      where: { userId },
    });

    if (!preference) {
      // 如果没有，创建新的
      preference = this.matchPreferenceRepository.create({
        userId,
        ...createMatchPreferenceDto,
      });
    } else {
      // 如果有，更新现有的
      Object.assign(preference, createMatchPreferenceDto);
    }

    return this.matchPreferenceRepository.save(preference);
  }

  // 获取用户的匹配偏好
  async getPreference(userId: number): Promise<MatchPreference> {
    const preference = await this.matchPreferenceRepository.findOne({
      where: { userId },
    });

    if (!preference) {
      // 如果没有，创建默认的
      return this.createOrUpdatePreference(userId, {});
    }

    return preference;
  }

  // 更新用户的匹配偏好
  async updatePreference(
    userId: number,
    updateMatchPreferenceDto: UpdateMatchPreferenceDto,
  ): Promise<MatchPreference> {
    const preference = await this.matchPreferenceRepository.findOne({
      where: { userId },
    });

    if (!preference) {
      throw new NotFoundException('匹配偏好不存在');
    }

    Object.assign(preference, updateMatchPreferenceDto);
    return this.matchPreferenceRepository.save(preference);
  }

  // 获取推荐的匹配用户
  async getRecommendations(userId: number): Promise<UserRecommendationDto[]> {
    // 获取当前用户信息
    const currentUser = await this.userRepository.findOne({
      where: { id: userId },
    });
    
    if (!currentUser) {
      throw new NotFoundException('用户不存在');
    }
    
    // 获取用户的匹配偏好
    const preference = await this.getPreference(userId);
    
    // 获取当前用户已经操作过的用户ID列表（喜欢或不喜欢过的）
    const existingMatches = await this.matchRepository.find({
      where: { userId },
      select: ['targetUserId'],
    });
    
    const excludeUserIds = existingMatches.map(match => match.targetUserId);
    // 添加自己的ID到排除列表
    excludeUserIds.push(userId);

    // 构建基础查询条件
    let query = this.userRepository.createQueryBuilder('user')
      .where('user.id NOT IN (:...excludeUserIds)', { excludeUserIds });
    
    // 应用年龄筛选
    if (preference.minAge) {
      query = query.andWhere('user.age >= :minAge', { minAge: preference.minAge });
    }
    if (preference.maxAge) {
      query = query.andWhere('user.age <= :maxAge', { maxAge: preference.maxAge });
    }
    
    // 应用性别筛选
    if (preference.preferredGenders && preference.preferredGenders.length > 0) {
      query = query.andWhere('user.gender IN (:...genders)', { genders: preference.preferredGenders });
    }
    
    // 应用身高筛选
    if (preference.minHeight) {
      query = query.andWhere('user.height >= :minHeight', { minHeight: preference.minHeight });
    }
    if (preference.maxHeight) {
      query = query.andWhere('user.height <= :maxHeight', { maxHeight: preference.maxHeight });
    }
    
    // 应用教育程度筛选
    if (preference.preferredEducation && preference.preferredEducation.length > 0) {
      query = query.andWhere('user.education IN (:...education)', { education: preference.preferredEducation });
    }
    
    // 应用职业筛选
    if (preference.preferredOccupations && preference.preferredOccupations.length > 0) {
      query = query.andWhere('user.occupation IN (:...occupations)', { occupations: preference.preferredOccupations });
    }
    
    // 应用收入筛选
    if (preference.preferredIncomes && preference.preferredIncomes.length > 0) {
      query = query.andWhere('user.income IN (:...incomes)', { incomes: preference.preferredIncomes });
    }
    
    // 应用位置筛选
    if (preference.preferredLocation) {
      query = query.andWhere('user.location LIKE :location', { location: `%${preference.preferredLocation}%` });
    }
    
    // 应用婚姻状态筛选
    if (preference.preferredMaritalStatus && preference.preferredMaritalStatus.length > 0) {
      query = query.andWhere('user.maritalStatus IN (:...maritalStatus)', { maritalStatus: preference.preferredMaritalStatus });
    }
    
    // 应用子女情况筛选
    if (preference.preferredHasChildren !== null && preference.preferredHasChildren !== undefined) {
      query = query.andWhere('user.hasChildren = :hasChildren', { hasChildren: preference.preferredHasChildren });
    }
    
    if (preference.preferredWantsChildren !== null && preference.preferredWantsChildren !== undefined) {
      query = query.andWhere('user.wantsChildren = :wantsChildren', { wantsChildren: preference.preferredWantsChildren });
    }
    
    // 应用生活习惯筛选
    if (preference.preferredSmoking && preference.preferredSmoking.length > 0) {
      query = query.andWhere('user.smoking IN (:...smoking)', { smoking: preference.preferredSmoking });
    }
    
    if (preference.preferredDrinking && preference.preferredDrinking.length > 0) {
      query = query.andWhere('user.drinking IN (:...drinking)', { drinking: preference.preferredDrinking });
    }
    
    if (preference.preferredDiet && preference.preferredDiet.length > 0) {
      query = query.andWhere('user.diet IN (:...diet)', { diet: preference.preferredDiet });
    }
    
    // 应用宠物筛选
    if (preference.acceptsPets !== null && preference.acceptsPets !== undefined) {
      if (preference.acceptsPets === false) {
        query = query.andWhere('user.hasPets = :hasPets', { hasPets: false });
      }
    }
    
    // 应用交友目的筛选
    if (preference.preferredRelationshipGoals && preference.preferredRelationshipGoals.length > 0) {
      query = query.andWhere('user.relationshipGoal IN (:...goals)', { goals: preference.preferredRelationshipGoals });
    }
    
    // 获取符合基本条件的用户，限制50个用于后续计算匹配度
    const potentialMatches = await query.limit(50).getMany();
    
    // 如果没有符合条件的用户，直接返回空数组
    if (potentialMatches.length === 0) {
      return [];
    }
    
    // 计算匹配度分数
    const scoredMatches = potentialMatches.map(user => {
      let totalScore = 0;
      let maxPossibleScore = 0;
      
      // 1. 年龄匹配度 (0-10分)
      const ageDifference = Math.abs(currentUser.age - user.age);
      const ageScore = Math.max(0, 10 - ageDifference * 0.5); // 每相差2岁减1分
      totalScore += ageScore * (preference.ageWeight || 5) / 5;
      maxPossibleScore += 10 * (preference.ageWeight || 5) / 5;
      
      // 2. 位置匹配度 (0-10分)
      let locationScore = 0;
      if (currentUser.location && user.location) {
        if (currentUser.location === user.location) {
          locationScore = 10; // 完全相同位置
        } else if (user.location.includes(currentUser.location) || currentUser.location.includes(user.location)) {
          locationScore = 7; // 部分匹配
        } else {
          locationScore = 3; // 不同位置
        }
      }
      totalScore += locationScore * (preference.locationWeight || 3) / 5;
      maxPossibleScore += 10 * (preference.locationWeight || 3) / 5;
      
      // 3. 兴趣爱好匹配度 (0-10分)
      let interestsScore = 0;
      if (currentUser.interests && user.interests && currentUser.interests.length > 0 && user.interests.length > 0) {
        const commonInterests = currentUser.interests.filter(interest => 
          user.interests.includes(interest)
        ).length;
        
        const totalInterests = Math.max(currentUser.interests.length, user.interests.length);
        interestsScore = (commonInterests / totalInterests) * 10;
      }
      
      // 如果有详细兴趣爱好，也计算匹配度
      let hobbiesScore = 0;
      if (currentUser.hobbies && user.hobbies && currentUser.hobbies.length > 0 && user.hobbies.length > 0) {
        const commonHobbies = currentUser.hobbies.filter(hobby => 
          user.hobbies.includes(hobby)
        ).length;
        
        const totalHobbies = Math.max(currentUser.hobbies.length, user.hobbies.length);
        hobbiesScore = (commonHobbies / totalHobbies) * 10;
      }
      
      // 取兴趣和爱好的平均分
      const combinedInterestScore = interestsScore > 0 && hobbiesScore > 0 
        ? (interestsScore + hobbiesScore) / 2 
        : interestsScore > 0 ? interestsScore : hobbiesScore;
      
      totalScore += combinedInterestScore * (preference.interestsWeight || 7) / 5;
      maxPossibleScore += 10 * (preference.interestsWeight || 7) / 5;
      
      // 4. 生活习惯匹配度 (0-10分)
      let lifestyleScore = 0;
      let lifestyleFactors = 0;
      
      // 吸烟习惯
      if (currentUser.smoking && user.smoking) {
        if (currentUser.smoking === user.smoking) {
          lifestyleScore += 10;
        } else if (
          (currentUser.smoking === 'never' && user.smoking === 'occasionally') ||
          (currentUser.smoking === 'occasionally' && user.smoking === 'never')
        ) {
          lifestyleScore += 5;
        } else {
          lifestyleScore += 2;
        }
        lifestyleFactors++;
      }
      
      // 饮酒习惯
      if (currentUser.drinking && user.drinking) {
        if (currentUser.drinking === user.drinking) {
          lifestyleScore += 10;
        } else if (
          (currentUser.drinking === 'never' && user.drinking === 'socially') ||
          (currentUser.drinking === 'socially' && user.drinking === 'never')
        ) {
          lifestyleScore += 5;
        } else {
          lifestyleScore += 2;
        }
        lifestyleFactors++;
      }
      
      // 饮食习惯
      if (currentUser.diet && user.diet) {
        if (currentUser.diet === user.diet) {
          lifestyleScore += 10;
        } else if (
          (currentUser.diet === 'vegetarian' && user.diet === 'vegan') ||
          (currentUser.diet === 'vegan' && user.diet === 'vegetarian')
        ) {
          lifestyleScore += 5;
        } else {
          lifestyleScore += 2;
        }
        lifestyleFactors++;
      }
      
      // 宠物
      if (currentUser.hasPets !== null && user.hasPets !== null) {
        if (currentUser.hasPets === user.hasPets) {
          lifestyleScore += 10;
        } else {
          lifestyleScore += 3;
        }
        lifestyleFactors++;
      }
      
      // 计算生活习惯平均分
      const avgLifestyleScore = lifestyleFactors > 0 ? lifestyleScore / lifestyleFactors : 0;
      totalScore += avgLifestyleScore * (preference.lifestyleWeight || 4) / 5;
      maxPossibleScore += 10 * (preference.lifestyleWeight || 4) / 5;
      
      // 5. 价值观匹配度 (0-10分)
      let valuesScore = 0;
      let valuesFactors = 0;
      
      // 价值观
      if (currentUser.values && user.values && currentUser.values.length > 0 && user.values.length > 0) {
        const commonValues = currentUser.values.filter(value => 
          user.values.includes(value)
        ).length;
        
        const totalValues = Math.max(currentUser.values.length, user.values.length);
        valuesScore += (commonValues / totalValues) * 10;
        valuesFactors++;
      }
      
      // 宗教信仰
      if (currentUser.religion && user.religion) {
        if (currentUser.religion === user.religion) {
          valuesScore += 10;
        } else {
          valuesScore += 3;
        }
        valuesFactors++;
      }
      
      // 政治观点
      if (currentUser.politicalView && user.politicalView) {
        if (currentUser.politicalView === user.politicalView) {
          valuesScore += 10;
        } else {
          valuesScore += 3;
        }
        valuesFactors++;
      }
      
      // 交友目的
      if (currentUser.relationshipGoal && user.relationshipGoal) {
        if (currentUser.relationshipGoal === user.relationshipGoal) {
          valuesScore += 10;
        } else if (
          (currentUser.relationshipGoal === 'serious' && user.relationshipGoal === 'marriage') ||
          (currentUser.relationshipGoal === 'marriage' && user.relationshipGoal === 'serious')
        ) {
          valuesScore += 7;
        } else {
          valuesScore += 2;
        }
        valuesFactors++;
      }
      
      // 计算价值观平均分
      const avgValuesScore = valuesFactors > 0 ? valuesScore / valuesFactors : 0;
      totalScore += avgValuesScore * (preference.valuesWeight || 6) / 5;
      maxPossibleScore += 10 * (preference.valuesWeight || 6) / 5;
      
      // 计算总匹配度百分比
      const compatibilityPercentage = maxPossibleScore > 0 
        ? Math.round((totalScore / maxPossibleScore) * 100) 
        : 50; // 如果没有足够信息，给一个中等分数
      
      return {
        user,
        compatibilityScore: compatibilityPercentage,
        // 保存各项分数，用于调试和解释匹配原因
        detailedScores: {
          age: ageScore,
          location: locationScore,
          interests: combinedInterestScore,
          lifestyle: avgLifestyleScore,
          values: avgValuesScore
        }
      };
    });
    
    // 按匹配度排序
    scoredMatches.sort((a, b) => b.compatibilityScore - a.compatibilityScore);
    
    // 返回排序后的用户列表（不包含分数信息）
    return scoredMatches.slice(0, 10).map(match => {
      // 创建UserRecommendationDto对象
      const recommendation = new UserRecommendationDto();
      
      // 复制用户信息
      Object.assign(recommendation, match.user);
      
      // 添加匹配度分数
      recommendation.compatibilityScore = match.compatibilityScore;
      
      return recommendation;
    });
  }

  // 创建匹配（喜欢或不喜欢）
  async createMatch(userId: number, createMatchDto: CreateMatchDto): Promise<Match> {
    // 检查目标用户是否存在
    const targetUser = await this.userRepository.findOne({
      where: { id: createMatchDto.targetUserId },
    });

    if (!targetUser) {
      throw new NotFoundException('目标用户不存在');
    }

    // 创建匹配记录
    const match = this.matchRepository.create({
      userId,
      targetUserId: createMatchDto.targetUserId,
      liked: createMatchDto.liked || false,
      matched: false,
    });

    // 保存匹配记录
    const savedMatch = await this.matchRepository.save(match);

    // 如果用户喜欢目标用户，检查是否互相喜欢（匹配成功）
    if (createMatchDto.liked) {
      const reverseMatch = await this.matchRepository.findOne({
        where: {
          userId: createMatchDto.targetUserId,
          targetUserId: userId,
          liked: true,
        },
      });

      // 如果互相喜欢，更新双方的匹配状态为已匹配
      if (reverseMatch) {
        savedMatch.matched = true;
        await this.matchRepository.save(savedMatch);

        reverseMatch.matched = true;
        await this.matchRepository.save(reverseMatch);

        // 创建初始聊天消息
        await this.chatService.create(null, {
          content: '你们已经匹配成功，开始聊天吧！',
          receiverId: userId,
          isAIMessage: true,
        });

        await this.chatService.create(null, {
          content: '你们已经匹配成功，开始聊天吧！',
          receiverId: createMatchDto.targetUserId,
          isAIMessage: true,
        });
      }
    }

    return savedMatch;
  }

  // 获取用户的匹配列表
  async getMatches(userId: number): Promise<any[]> {
    // 查询与用户匹配成功的记录
    const matches = await this.matchRepository.find({
      where: {
        userId,
        matched: true,
      },
      relations: ['targetUser'],
    });

    // 转换为前端需要的格式
    return matches.map(match => ({
      id: match.targetUser.id,
      name: match.targetUser.name,
      age: match.targetUser.age,
      gender: match.targetUser.gender,
      location: match.targetUser.location,
      bio: match.targetUser.bio,
      interests: match.targetUser.interests,
      hobbies: match.targetUser.hobbies,
      education: match.targetUser.education,
      occupation: match.targetUser.occupation,
      maritalStatus: match.targetUser.maritalStatus,
      hasChildren: match.targetUser.hasChildren,
      wantsChildren: match.targetUser.wantsChildren,
      smoking: match.targetUser.smoking,
      drinking: match.targetUser.drinking,
      diet: match.targetUser.diet,
      hasPets: match.targetUser.hasPets,
      pets: match.targetUser.pets,
      values: match.targetUser.values,
      religion: match.targetUser.religion,
      politicalView: match.targetUser.politicalView,
      relationshipGoal: match.targetUser.relationshipGoal,
      languages: match.targetUser.languages,
      avatar: `https://randomuser.me/api/portraits/${match.targetUser.gender === 'female' ? 'women' : 'men'}/${Math.floor(Math.random() * 100)}.jpg`,
      matchedAt: match.createdAt,
    }));
  }
}